home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / Apache 1.0 / src / mod_auth.c < prev    next >
Text File  |  1995-12-04  |  8KB  |  263 lines

  1.  
  2. /* ====================================================================
  3.  * Copyright (c) 1995 The Apache Group.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer. 
  11.  *
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in
  14.  *    the documentation and/or other materials provided with the
  15.  *    distribution.
  16.  *
  17.  * 3. All advertising materials mentioning features or use of this
  18.  *    software must display the following acknowledgment:
  19.  *    "This product includes software developed by the Apache Group
  20.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  21.  *
  22.  * 4. The names "Apache Server" and "Apache Group" must not be used to
  23.  *    endorse or promote products derived from this software without
  24.  *    prior written permission.
  25.  *
  26.  * 5. Redistributions of any form whatsoever must retain the following
  27.  *    acknowledgment:
  28.  *    "This product includes software developed by the Apache Group
  29.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  30.  *
  31.  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  32.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  33.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  34.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  35.  * IT'S CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  36.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  37.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  38.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  40.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  41.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  42.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  43.  * ====================================================================
  44.  *
  45.  * This software consists of voluntary contributions made by many
  46.  * individuals on behalf of the Apache Group and was originally based
  47.  * on public domain software written at the National Center for
  48.  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
  49.  * For more information on the Apache Group and the Apache HTTP server
  50.  * project, please see <http://www.apache.org/>.
  51.  *
  52.  */
  53.  
  54.  
  55. /*
  56.  * http_auth: authentication
  57.  * 
  58.  * Rob McCool
  59.  * 
  60.  * Adapted to Shambhala by rst.
  61.  */
  62.  
  63. #include "httpd.h"
  64. #include "http_config.h"
  65. #include "http_core.h"
  66. #include "http_log.h"
  67. #include "http_protocol.h"
  68.  
  69. typedef struct auth_config_struct {
  70.     char *auth_pwfile;
  71.     char *auth_grpfile;
  72. } auth_config_rec;
  73.  
  74. void *create_auth_dir_config (pool *p, char *d)
  75. {
  76.     return pcalloc (p, sizeof(auth_config_rec));
  77. }
  78.  
  79. command_rec auth_cmds[] = {
  80. { "AuthUserFile", set_string_slot,
  81.     (void*)XtOffsetOf(auth_config_rec,auth_pwfile), OR_AUTHCFG, TAKE1, NULL },
  82. { "AuthGroupFile", set_string_slot,
  83.     (void*)XtOffsetOf(auth_config_rec,auth_grpfile), OR_AUTHCFG, TAKE1, NULL },
  84. { NULL }
  85. };
  86.  
  87. module auth_module;
  88.  
  89. char *get_pw(request_rec *r, char *user, char *auth_pwfile)
  90. {
  91.     FILE *f;
  92.     char l[MAX_STRING_LEN];
  93.     char *rpw, *w;
  94.  
  95.     if(!(f=pfopen(r->pool, auth_pwfile, "r"))) {
  96.         log_reason ("Could not open password file", auth_pwfile, r);
  97.     return NULL;
  98.     }
  99.     while(!(cfg_getline(l,MAX_STRING_LEN,f))) {
  100.         if((l[0] == '#') || (!l[0])) continue;
  101.     rpw = l;
  102.         w = getword(r->pool, &rpw, ':');
  103.  
  104.         if(!strcmp(user,w)) {
  105.         pfclose(r->pool, f);
  106.             return pstrdup (r->pool, rpw);
  107.     }
  108.     }
  109.     pfclose(r->pool, f);
  110.     return NULL;
  111. }
  112.  
  113. table *groups_for_user (pool *p, char *user, char *grpfile) {
  114.     FILE *f;
  115.     table *grps = make_table (p, 15);
  116.     pool *sp;
  117.     char l[MAX_STRING_LEN];
  118.     char *group_name, *ll, *w;
  119.  
  120.     if(!(f=pfopen(p, grpfile, "r")))
  121.         return NULL;
  122.  
  123.     sp = make_sub_pool (p);
  124.     
  125.     while(!(cfg_getline(l,MAX_STRING_LEN,f))) {
  126.         if((l[0] == '#') || (!l[0])) continue;
  127.     ll = l;
  128.     clear_pool (sp);
  129.     
  130.         group_name = getword(sp, &ll, ':');
  131.  
  132.     while(ll[0]) {
  133.         w = getword_conf (sp, &ll);
  134.         if(!strcmp(w,user)) {
  135.         table_set (grps, group_name, "in");
  136.         break;
  137.         }
  138.     }
  139.     }
  140.     pfclose(p, f);
  141.     destroy_pool (sp);
  142.     return grps;
  143. }
  144.  
  145. /* These functions return 0 if client is OK, and proper error status
  146.  * if not... either AUTH_REQUIRED, if we made a check, and it failed, or
  147.  * SERVER_ERROR, if things are so totally confused that we couldn't
  148.  * figure out how to tell if the client is authorized or not.
  149.  *
  150.  * If they return DECLINED, and all other modules also decline, that's
  151.  * treated by the server core as a configuration error, logged and
  152.  * reported as such.
  153.  */
  154.  
  155. /* Determine user ID, and check if it really is that user, for HTTP
  156.  * basic authentication...
  157.  */
  158.  
  159. int authenticate_basic_user (request_rec *r)
  160. {
  161.     auth_config_rec *sec =
  162.       (auth_config_rec *)get_module_config (r->per_dir_config, &auth_module);
  163.     conn_rec *c = r->connection;
  164.     char *sent_pw, *real_pw;
  165.     char errstr[MAX_STRING_LEN];
  166.     int res;
  167.     
  168.     if ((res = get_basic_auth_pw (r, &sent_pw))) return res;
  169.     
  170.     if(!sec->auth_pwfile) 
  171.         return DECLINED;
  172.     
  173.     if (!(real_pw = get_pw(r, c->user, sec->auth_pwfile))) {
  174.         sprintf(errstr,"user %s not found",c->user);
  175.     log_reason (errstr, r->uri, r);
  176.     note_basic_auth_failure (r);
  177.     return AUTH_REQUIRED;
  178.     }
  179.     /* anyone know where the prototype for crypt is? */
  180.     if(strcmp(real_pw,(char *)crypt(sent_pw,real_pw))) {
  181.         sprintf(errstr,"user %s: password mismatch",c->user);
  182.     log_reason (errstr, r->uri, r);
  183.     note_basic_auth_failure (r);
  184.     return AUTH_REQUIRED;
  185.     }
  186.     return OK;
  187. }
  188.     
  189. /* Checking ID */
  190.     
  191. int check_user_access (request_rec *r) {
  192.     auth_config_rec *sec =
  193.       (auth_config_rec *)get_module_config (r->per_dir_config, &auth_module);
  194.     char *user = r->connection->user;
  195.     int m = r->method_number;
  196.     
  197.     register int x;
  198.     char *t, *w;
  199.     table *grpstatus;
  200.     array_header *reqs_arr = requires (r);
  201.     require_line *reqs;
  202.  
  203.     /* BUG FIX: tadc, 11-Nov-1995.  If there is no "requires" directive, 
  204.      * then any user will do.
  205.      */
  206.     if (!reqs_arr)
  207.         return (OK);
  208.     reqs = (require_line *)reqs_arr->elts;
  209.  
  210.     if(sec->auth_grpfile)
  211.         grpstatus = groups_for_user (r->pool, user, sec->auth_grpfile);
  212.     else
  213.         grpstatus = NULL;
  214.  
  215.     for(x=0; x < reqs_arr->nelts; x++) {
  216.       
  217.     if (! (reqs[x].method_mask & (1 << m))) continue;
  218.     
  219.         t = reqs[x].requirement;
  220.         w = getword(r->pool, &t, ' ');
  221.         if(!strcmp(w,"valid-user"))
  222.             return OK;
  223.         if(!strcmp(w,"user")) {
  224.             while(t[0]) {
  225.                 w = getword_conf (r->pool, &t);
  226.                 if(!strcmp(user,w))
  227.                     return OK;
  228.             }
  229.         }
  230.         else if(!strcmp(w,"group")) {
  231.             if(!grpstatus) 
  232.             return DECLINED;    /* DBM group?  Something else? */
  233.         
  234.             while(t[0]) {
  235.                 w = getword_conf(r->pool, &t);
  236.                 if(table_get (grpstatus, w))
  237.             return OK;
  238.             }
  239.         }
  240.     }
  241.     
  242.     note_basic_auth_failure (r);
  243.     return AUTH_REQUIRED;
  244. }
  245.  
  246. module auth_module = {
  247.    STANDARD_MODULE_STUFF,
  248.    NULL,            /* initializer */
  249.    create_auth_dir_config,    /* dir config creater */
  250.    NULL,            /* dir merger --- default is to override */
  251.    NULL,            /* server config */
  252.    NULL,            /* merge server config */
  253.    auth_cmds,            /* command table */
  254.    NULL,            /* handlers */
  255.    NULL,            /* filename translation */
  256.    authenticate_basic_user,    /* check_user_id */
  257.    check_user_access,        /* check auth */
  258.    NULL,            /* check access */
  259.    NULL,            /* type_checker */
  260.    NULL,            /* fixups */
  261.    NULL                /* logger */
  262. };
  263.